using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;
using JoyfulHomeJourney.BackEnd.Infrastructure.Atrributes;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Requests;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Requests.Objects;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Responses;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Responses.Objects;
using JoyfulHomeJourney.BackEnd.Infrastructure.EFCore;
using JoyfulHomeJourney.BackEnd.Infrastructure.Tools;
using JoyfulHomeJourney.BackEnd.Server.EFCore;
using JoyfulHomeJourney.BackEnd.Server.Instances.Extends.Requests;
using JoyfulHomeJourney.BackEnd.Server.Instances.Extends.Responses;
using JoyfulHomeJourney.BackEnd.Server.Interfaces;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace JoyfulHomeJourney.BackEnd.Server.Instances
{
/// <summary>
/// 一个类包含了服务类所需的所有仓库表的实例，仅提供给该服务类使用，请将所有服务类所需的仓库表的实例都放在该类中。
/// 仓库表的实例指提供了操作数据库指定表的所有方法的对象
/// </summary>
	internal class OfflineOrdersEF
	{
		public OfflineOrdersEF(DbContext dbContext)
		{
			offlineOrdersServerEF = new OfflineOrdersServerEF(dbContext);
            vipDiscountsServerEF = new VipDiscountsServerEF(dbContext);
            vipDeductionsServerEF = new VipDeductionsServerEF(dbContext);
            sysAccountsServerEF = new SysAccountsServerEF(dbContext);
            sysVipPackagesServerEF = new SysVipPackagesServerEF(dbContext);
            sysProductsServerEF = new SysProductsServerEF(dbContext);
            vipsServerEF = new VipsServerEF(dbContext);
            offlineOrderDetailsServerEF = new OfflineOrderDetailsServerEF(dbContext);
            sysCustomersServerEF = new SysCustomersServerEF(dbContext);
            employeesServerEF = new EmployeesServerEF(dbContext);
        }
		public OfflineOrdersServerEF offlineOrdersServerEF { get; set; }
        public VipDiscountsServerEF vipDiscountsServerEF { get; set; }
        public VipDeductionsServerEF vipDeductionsServerEF { get; set; }
        public SysAccountsServerEF sysAccountsServerEF { get; set; }
        public SysVipPackagesServerEF sysVipPackagesServerEF { get; set; }
        public SysProductsServerEF sysProductsServerEF { get; set; }
        public VipsServerEF vipsServerEF { get; set; }
        public OfflineOrderDetailsServerEF offlineOrderDetailsServerEF { get; set; }
        public SysCustomersServerEF sysCustomersServerEF { get; set; }
        public EmployeesServerEF employeesServerEF { get; set; }
    }
	[InjectClass]
	public class OfflineOrdersServer : IOfflineOrdersServer
	{
		private readonly OfflineOrdersEF _offlineOrdersEF;//包含所有所需仓库表实现的对象
		// 请不要修改该构造方法,也无需添加属性，而应该在上面的EF类中添加属性和构造函数赋值语句
		public OfflineOrdersServer(DbContext dbContext)
		{
			_offlineOrdersEF = new OfflineOrdersEF(dbContext);
		}
		
        /// <summary>
        /// 创建Vip订单表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ResponseApiDto> AddordersAsync(RequestOfflineOrdersDto dto)
        {
            //获取汽车店id
            string cid = await _offlineOrdersEF.employeesServerEF.Query(d => d.EAccountId == dto.cid).Select(d => d.ECarShopId).FirstOrDefaultAsync();
            //获取VIP的抵扣和折扣
            var disid = await _offlineOrdersEF.vipDiscountsServerEF.Query(d => d.VdVipId == dto.vipId).Select(d => d.VdDiscountId).SingleOrDefaultAsync();
            var dedid = await _offlineOrdersEF.vipDeductionsServerEF.Query(d => d.VdVipId == dto.vipId).Select(d => d.VdDeductionId).SingleOrDefaultAsync();
            //获取vip的永久折扣
            var vipdis = await _offlineOrdersEF.vipsServerEF.Query(d => d.VId == dto.vipId).Select(d => d.VFoeverDiscount).SingleOrDefaultAsync();
            //获取产品ID
            var prid = await _offlineOrdersEF.sysVipPackagesServerEF.Query(d => d.VpVipId == dto.vipId).Select(d => d.VpProductId).SingleOrDefaultAsync();
            //获取产品消息
            var pr = await _offlineOrdersEF.sysProductsServerEF.Query(d => d.PId == prid).Select(d => new
            {
                name=d.PName,
                price=d.PPrice,
                payPrice=(int)d.PPrice,//实付价格
                discount =d.PDiscount,
                dedcount=d.PDeduction,

            }).SingleAsync();
            
            OfflineOrders carShop = new OfflineOrders()
			{
				OoStatus= "未支付",
				OoPayCount= 0,
				OdDiscountId= disid,
				OdDeductionId= dedid,
                OoCarShopId=cid,
            };
            int affectedRows = 0;
            // 生成客户账号
            string salt = Tools.Guid_1();
            await _offlineOrdersEF.offlineOrdersServerEF.ExecuteInTransactionAsync(async () =>
            {
                SysAccounts newAccount = new SysAccounts
                {
                    AAccount = dto.email,
                    AName = dto.name,
                    ARole = "user",
                    ASalt = salt,
                    APassword = Encrypt.GetMd5Hash(dto.password + salt)
                };
                affectedRows += await _offlineOrdersEF.sysAccountsServerEF.AddAsync(newAccount);
                carShop.OoAccountId = newAccount.AId;
                affectedRows += await _offlineOrdersEF.offlineOrdersServerEF.AddAsync(carShop);
                SysCustomers sysCustomers = new SysCustomers 
                {
                    CAccount= newAccount.AId,
                    CEmail=null,
                    CPhoneNumber = dto.email,
                    CLastLoginTime=null,
                    CAvatar=null,
                    CGender=null,
                    CBirthday=null,
                    CAddress=null,
                    CIpAddress=null,
                    CVip=dto.vipId,
                    CStatus= "pending",
                };
                affectedRows += await _offlineOrdersEF.sysCustomersServerEF.AddAsync(sysCustomers);
                OfflineOrderDetails offlineOrderDetails = new OfflineOrderDetails 
                { 
                    OodOfflineOrderId = carShop.OoId,
                    OodProductId= prid,
                    OodCount= 1,
                    OodProductName=pr.name,
                    OodSinglePrice=pr.price*1,
                    OodProductPrice=pr.price,
                    OodProductPayPrice=pr.payPrice,
                    OodVipDiscount= (int)(vipdis*100),
                    OodDeduction=pr.dedcount,
                    OodDiscount=pr.discount,
                };
                affectedRows += await _offlineOrdersEF.offlineOrderDetailsServerEF.AddAsync(offlineOrderDetails);
            }, () =>
            {
                affectedRows = 0; return null;
            });
            return ResponseApiDto.Create(affectedRows, data: carShop.OoId);
        }
        /// <summary>
        /// 创建结账订单表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ResponseApiDto> add_jz_primary(add_jz_primary_DTO dto, string uid)
        {
            //获取汽车店id
            string cid = await _offlineOrdersEF.employeesServerEF.Query(d => d.EAccountId == uid).Select(d => d.ECarShopId).FirstOrDefaultAsync();

            OfflineOrders carShop = new OfflineOrders()
            {
                OoStatus = "未支付",
                OoPayCount = dto.jz,
                OdDiscountId = null,
                OdDeductionId = null,
                OoCarShopId = cid,
                OoAccountId=null,
            };
            int i= await _offlineOrdersEF.offlineOrdersServerEF.AddAsync(carShop);
            if (i==1)
            {
                foreach (var d in dto.dto)
                {
                    OfflineOrderDetails offlineOrderDetails = new OfflineOrderDetails
                    {
                        OodOfflineOrderId = carShop.OoId,
                        OodProductId = d.PId,
                        OodCount = d.count,
                        OodProductName = d.PName,
                        OodSinglePrice = (decimal)d.PPrice,
                        OodProductPrice = (decimal)d.PPrice,
                        OodProductPayPrice = (decimal)d.count*d.PPrice,
                        OodVipDiscount = 1,
                        OodDeduction = 0,
                        OodDiscount = 1,
                    };
                    _offlineOrdersEF.offlineOrderDetailsServerEF.Add(offlineOrderDetails);
                }
                return ResponseApiDto.Create(i, data:carShop.OoId);
            }
            return ResponseApiDto.Fail();
        }

        /// <summary>
        /// 删除订单表
        /// </summary>
        /// <param id="id"></param>
        /// <returns></returns>
        public async Task<ResponseApiDto> dele_offline_orders(string id)
        {
            var ip = await _offlineOrdersEF.offlineOrderDetailsServerEF.Query(d => d.OodOfflineOrderId == id).SingleOrDefaultAsync();
            var de= await _offlineOrdersEF.offlineOrderDetailsServerEF.DeleteAsync(ip);
            if (de==1) {
                var iq = await _offlineOrdersEF.offlineOrdersServerEF.Query(d => d.OoId == id).SingleOrDefaultAsync();
                return ResponseApiDto.Create(await _offlineOrdersEF.offlineOrdersServerEF.DeleteAsync(iq));
            }
            return ResponseApiDto.Fail();
        }

        /// <summary>
        /// 获取vip订单表数据
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public async Task<ResponseApiDto> Get_offline_orders(int page, int limit, string key, string statusFilter, string uid)
        { 
            //获取汽车店id
            string cid = await _offlineOrdersEF.employeesServerEF.Query(d => d.EAccountId == uid).Select(d => d.ECarShopId).FirstOrDefaultAsync();
            int total = 0;
            key = key ?? "";
            statusFilter = statusFilter ?? "";
            List<OfflineOrders> ip = await _offlineOrdersEF.offlineOrdersServerEF.Pagination1(d =>d.OoId.Contains(key)&&d.OoStatus.Contains(statusFilter)&&d.OoCarShopId==cid, false, d => d.OoCreateAt, out total, page, limit).ToListAsync();
            List<object> data = new List<object>();
            foreach (var group in ip)
            {
                data.Add(new
                {
                    Ordernumber=group.OoId,
                    status=group.OoStatus,
                    amount=group.OoPayCount,
                    Creationtime=group.OoCreateAt,
                    Paymenttime=group.OoUpdateAt,
                    detailslist = _offlineOrdersEF.offlineOrderDetailsServerEF.Query(d => d.OodOfflineOrderId == group.OoId).Select(d => new
                    {
                        Itemnumber=d.OodProductId,
                        name=d.OodProductName,
                        cpunt=d.OodCount,
                        unitprice=d.OodSinglePrice,
                        discount=d.OodDiscount,
                        dedcount=d.OodDeduction,
                        creationtime = group.OoCreateAt,
                    }).ToList(),
                });
            }
            return ResponseApiDto.Success("数据已获取", new ResponsePaginationDto { total = total, data = data });
        }
        /// <summary>
        /// 获取结账订单数据
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseApiDto> Get_sys_products(string id, string uid)
        {
            //获取汽车店id
            string cid = await _offlineOrdersEF.employeesServerEF.Query(d => d.EAccountId == uid).Select(d => d.ECarShopId).FirstOrDefaultAsync();
            List<OfflineOrders> ip = await _offlineOrdersEF.offlineOrdersServerEF.Query(d => d.OoId==id&& d.OoCarShopId == cid).ToListAsync();
            List<object> data = new List<object>();
            foreach (var group in ip)
            {
                data.Add(new
                {
                    Ordernumber =group.OoId,
                    status = group.OoStatus,
                    amount = group.OoPayCount,
                    Creationtime = group.OoCreateAt,
                    Paymenttime = group.OoUpdateAt,
                    detailslist = _offlineOrdersEF.offlineOrderDetailsServerEF.Query(d => d.OodOfflineOrderId == group.OoId).Select(d => new
                    {
                        Itemnumber = d.OodProductId,
                        name = d.OodProductName,
                        cpunt = d.OodCount,
                        unitprice = d.OodSinglePrice,
                        discount = d.OodDiscount,
                        dedcount = d.OodDeduction,
                        product = d.OodProductPayPrice,
                    }).ToList(),
                });
            }
            return ResponseApiDto.Success("数据已获取", new ResponsePaginationDto {  data = data });


        }
        /// <summary>
        /// 现金支付
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public async Task<ResponseApiDto> up_offjz(Pay_Rerquest_Dto dto)
        {
            var ip = await _offlineOrdersEF.offlineOrdersServerEF.Query(d => d.OoId == dto.oid).SingleOrDefaultAsync();
            ip.OoStatus = "已支付";
            ip.OoPayCount = (decimal)dto.money;
            ip.OoUpdateAt = System.DateTime.Now;
            return ResponseApiDto.Create(await _offlineOrdersEF.offlineOrdersServerEF.UpdateAllProperNotNullAsync(ip));
        }
        /// <summary>
        /// 微信支付
        /// </summary>
        /// <param name="trade_order_id"></param>
        /// <param name="total_fee"></param>
        /// <exception cref="System.NotImplementedException"></exception>
        public async Task up_offwxjz(string trade_order_id, string total_fee)
        {
            var ip = _offlineOrdersEF.offlineOrdersServerEF.Query(d => d.OoId == trade_order_id).SingleOrDefault();
            ip.OoStatus = "已支付";
            ip.OoPayCount =Convert.ToDecimal( total_fee);
            ip.OoUpdateAt = System.DateTime.Now;
            var k= await _offlineOrdersEF.offlineOrdersServerEF.UpdateAllProperAsync(ip);
        }
    }
}
